package com.example.xiaoming.activity;

import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;

import android.Manifest;

import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.PendingIntent;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothHidDevice;
import android.bluetooth.BluetoothHidDeviceAppQosSettings;
import android.bluetooth.BluetoothHidDeviceAppSdpSettings;
import android.bluetooth.BluetoothManager;
import android.bluetooth.BluetoothProfile;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.PackageManager;
import android.database.DataSetObserver;
import android.graphics.Color;
import android.hardware.usb.UsbConstants;
import android.hardware.usb.UsbDevice;
import android.hardware.usb.UsbDeviceConnection;
import android.hardware.usb.UsbEndpoint;
import android.hardware.usb.UsbInterface;
import android.hardware.usb.UsbManager;
import android.location.LocationManager;
import android.os.Build;
import android.os.Bundle;
import android.provider.Settings;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Adapter;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.GridView;
import android.widget.SimpleAdapter;
import android.widget.Toast;

import com.example.xiaoming.R;
import com.example.xiaoming.util.HidConsts;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Executor;

import static com.example.xiaoming.activity.MainActivity.USBReceiver.ACTION_USB_PERMISSION;

public class MainActivity extends AppCompatActivity {


    private final static int REQUEST_EXTERNAL_STORAGE = 1;
    private final static int REQUEST_CODE_ACCESS_COARSE_LOCATION = 0xf9;
    private final static int GPS_REQUEST_CODE = 0xf7;
    private final static int GPS_REQUEST_DIALOG = 0xf1;
    private final static String[] DIALOG_SHOW_TEXT = {"是否开启GPS", ""};
    private final static String[] PERMISSIONS_STORAGE = {
            Manifest.permission.ACCESS_COARSE_LOCATION,
            Manifest.permission.READ_EXTERNAL_STORAGE,
            Manifest.permission.WRITE_EXTERNAL_STORAGE,
            Settings.ACTION_MANAGE_OVERLAY_PERMISSION
    };
    private static final String TAG = MainActivity.class.getSimpleName();
    private LocationManager locationManager;
    private Context context;
    private BluetoothHidDevice hidDevice;
    private GridView gv_keyboard;
    private BluetoothDevice bluetoothDevice;
    private UsbManager usbManager;
    private UsbDeviceConnection usbConnection;
    private PendingIntent mPermissionIntent;
    private BroadcastReceiver usbReceiver;
    private String[] command=new String[]{"连接","鼠标"};

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        context = this;
        gv_keyboard = findViewById(R.id.gv_keyboard);
        List<Map<String, String>> list = new ArrayList<>();
        int a = 0;
        Map map;
        for (int i = 0; i < 101; i++) {
            map = new HashMap();
            a += i;
            map.put("item", a + "");
            map.put("color", i % 2 == 1 ? R.drawable.dialog_background : null);
            list.add(map);
        }
        SimpleAdapter adapter = new SimpleAdapter(context, list, R.layout.item_gv, new String[]{"item", "color"}, new int[]{R.id.tv_item, R.id.im_item});
        gv_keyboard.setAdapter(adapter);
        permissionManage();

        gv_keyboard.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                hidDevice.sendReport(bluetoothDevice, 0, new byte[]{(byte) position});
            }
        });
        BluetoothAdapter.getDefaultAdapter().getProfileProxy(context, mProfileServiceListener, BluetoothProfile.HID_DEVICE);

    }

    private BluetoothHidDevice.Callback mCallback = new BluetoothHidDevice.Callback() {
        @Override
        public void onAppStatusChanged(BluetoothDevice pluggedDevice, boolean registered) {
            super.onAppStatusChanged(pluggedDevice, registered);
            Log.e(TAG, "onAppStatusChanged");
        }

        @Override
        public void onConnectionStateChanged(BluetoothDevice device, int state) {
            super.onConnectionStateChanged(device, state);
            Log.e(TAG, "onConnect");
            bluetoothDevice = BluetoothAdapter.getDefaultAdapter().getRemoteDevice(device.getAddress());
        }

        @Override
        public void onGetReport(BluetoothDevice device, byte type, byte id, int bufferSize) {
            super.onGetReport(device, type, id, bufferSize);
        }

        @Override
        public void onSetReport(BluetoothDevice device, byte type, byte id, byte[] data) {
            super.onSetReport(device, type, id, data);
        }

        @Override
        public void onSetProtocol(BluetoothDevice device, byte protocol) {
            super.onSetProtocol(device, protocol);
        }

        @Override
        public void onInterruptData(BluetoothDevice device, byte reportId, byte[] data) {
            super.onInterruptData(device, reportId, data);
        }

        @Override
        public void onVirtualCableUnplug(BluetoothDevice device) {
            super.onVirtualCableUnplug(device);
        }
    };
    private BluetoothProfile.ServiceListener mProfileServiceListener = new BluetoothProfile.ServiceListener() {

        @Override
        public void onServiceDisconnected(int profile) {
            if (profile == BluetoothProfile.HEALTH) {
//                mBluetoothHealth = null;
            }
        }

        @SuppressLint("NewApi")
        @Override
        public void onServiceConnected(int profile, BluetoothProfile proxy) {
            Log.e(TAG, "connect");
            if (proxy.getConnectedDevices().size() > 0) {
                bluetoothDevice = proxy.getConnectedDevices().get(0);
            }
            if (profile == BluetoothProfile.HEALTH) {
                hidDevice = (BluetoothHidDevice) proxy;
                // 获取代理对象之后就进行注册
                BluetoothHidDeviceAppSdpSettings sdp = new BluetoothHidDeviceAppSdpSettings(
                        HidConsts.NAME, HidConsts.DESCRIPTION, HidConsts.PROVIDER,
                        BluetoothHidDevice.SUBCLASS1_COMBO, HidConsts.DESCRIPTOR);
                BluetoothHidDeviceAppQosSettings inQos = new BluetoothHidDeviceAppQosSettings(
                        BluetoothHidDeviceAppQosSettings.SERVICE_GUARANTEED, 200, 2, 200,
                        10000 /* 10 ms */, 10000 /* 10 ms */);
                BluetoothHidDeviceAppQosSettings outQos = new BluetoothHidDeviceAppQosSettings(
                        BluetoothHidDeviceAppQosSettings.SERVICE_GUARANTEED, 900, 9, 900,
                        10000 /* 10 ms */, 10000 /* 10 ms */);

                boolean result = hidDevice.registerApp(sdp, inQos, outQos, new Executor() {
                    @Override
                    public void execute(Runnable command) {

                    }
                }, mCallback);
            }
        }
    };


    private void permissionManage() {
        locationManager = (LocationManager) this.getSystemService(Context.LOCATION_SERVICE);
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
                if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.ACCESS_COARSE_LOCATION)) {
                    Toast.makeText(this, "自Android 6.0开始需要打开位置权限才可以搜索到蓝牙设备", Toast.LENGTH_SHORT).show();
                }
                ActivityCompat.requestPermissions(this, PERMISSIONS_STORAGE, REQUEST_CODE_ACCESS_COARSE_LOCATION);
            }
            openGPSSettings();
        }
    }

    private void openGPSSettings() {
        if (locationManager.isProviderEnabled(android.location.LocationManager.GPS_PROVIDER)) {
            return;
        } else {
            Toast.makeText(this, "请开启GPS！", Toast.LENGTH_SHORT).show();
            Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
            startActivityForResult(intent, GPS_REQUEST_CODE);
        }
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        switch (requestCode) {
            case GPS_REQUEST_DIALOG:
                if (data.getBooleanExtra(DialogActivity.AGREE, true)) {
                    openGPSSettings();
                } else {
                    finish();
                }
                break;
            case GPS_REQUEST_CODE:
                if (!locationManager.isProviderEnabled(android.location.LocationManager.GPS_PROVIDER)) {
                    dialog1();
                }
                break;
            default:
                break;
        }
    }

    private void dialog1() {
        Intent intent = new Intent(this, DialogActivity.class);
        intent.putExtra(DialogActivity.DIALOG, DIALOG_SHOW_TEXT[0]);
        startActivityForResult(intent, GPS_REQUEST_DIALOG);
    }


    UsbInterface usbInterface;

    /**
     * 判断对应 USB 设备是否有权限
     */
    public boolean hasPermission(UsbDevice device) {
        return usbManager.hasPermission(device);
    }

    /**
     * 请求获取指定 USB 设备的权限
     */
    public void requestPermission(UsbDevice device) {
        if (device != null) {
            if (usbManager.hasPermission(device)) {
                Toast.makeText(context, "已经获取到权限", Toast.LENGTH_SHORT).show();
            } else {
                if (mPermissionIntent != null) {
                    usbManager.requestPermission(device, mPermissionIntent);
                    Toast.makeText(context, "请求USB权限", Toast.LENGTH_SHORT).show();
                } else {
                    Toast.makeText(context, "请注册USB广播", Toast.LENGTH_LONG).show();
                }
            }
        }
    }

    public void registerReceiver(Activity context) {
        mPermissionIntent = PendingIntent.getBroadcast(context, 0, new Intent(ACTION_USB_PERMISSION), 0);
        IntentFilter filter = new IntentFilter(ACTION_USB_PERMISSION);
        filter.addAction(UsbManager.ACTION_USB_DEVICE_DETACHED);
        filter.addAction(UsbManager.ACTION_USB_DEVICE_ATTACHED);
        context.registerReceiver(usbReceiver, filter);
    }

    public List<UsbDevice> getDeviceList() {
        HashMap<String, UsbDevice> deviceList = usbManager.getDeviceList();
        Iterator<UsbDevice> deviceIterator = deviceList.values().iterator();
        List<UsbDevice> usbDevices = new ArrayList<>();
        while (deviceIterator.hasNext()) {
            UsbDevice device = deviceIterator.next();
            usbDevices.add(device);
            Log.e("USBUtil", "getDeviceList: " + device.getDeviceName());
        }
        return usbDevices;
    }

    public class USBReceiver extends BroadcastReceiver {
        public static final String ACTION_USB_PERMISSION = "com.android.example.USB_PERMISSION";

        @Override
        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();
            if (ACTION_USB_PERMISSION.equals(action)) {
                // 获取权限结果的广播
                synchronized (this) {
                    UsbDevice device = (UsbDevice) intent.getParcelableExtra(UsbManager.EXTRA_DEVICE);
                    if (device != null) {
                        //call method to set up device communication
                        if (intent.getBooleanExtra(UsbManager.EXTRA_PERMISSION_GRANTED, false)) {
                            Log.e("USBReceiver", "获取权限成功：" + device.getDeviceName());
                        } else {
                            Log.e("USBReceiver", "获取权限失败：" + device.getDeviceName());
                        }
                    }
                }
            } else if (UsbManager.ACTION_USB_DEVICE_ATTACHED.equals(action)) {
                // 有新的设备插入了，在这里一般会判断这个设备是不是我们想要的，是的话就去请求权限
            } else if (UsbManager.ACTION_USB_DEVICE_DETACHED.equals(action)) {
                // 有设备拔出了
            }
        }
//    }

        public boolean openPort(UsbDevice device) {
            //获取设备接口，一般只有一个，多个的自己研究去
            usbInterface = device.getInterface(0);

            // 判断是否有权限
            if (hasPermission(device)) {
                // 打开设备，获取 UsbDeviceConnection 对象，连接设备，用于后面的通讯
                usbConnection = usbManager.openDevice(device);

                if (usbConnection == null) {
                    return false;
                }
                if (usbConnection.claimInterface(usbInterface, true)) {
                    Toast.makeText(context, "找到 USB 设备接口", Toast.LENGTH_SHORT).show();
                } else {
                    usbConnection.close();
                    Toast.makeText(context, "没有找到 USB 设备接口", Toast.LENGTH_SHORT).show();
                    return false;
                }
            } else {
                Toast.makeText(context, "没有 USB 权限", Toast.LENGTH_SHORT).show();
                return false;
            }

            //获取接口上的两个端点，分别对应 OUT 和 IN
            for (int i = 0; i < usbInterface.getEndpointCount(); ++i) {
                UsbEndpoint end = usbInterface.getEndpoint(i);
                if (end.getDirection() == UsbConstants.USB_DIR_IN) {
                    usbEndpointIn = end;
                } else {
                    usbEndpointOut = end;
                }
            }
            return true;
        }
    }

    UsbEndpoint usbEndpointIn;
    UsbEndpoint usbEndpointOut;
}
